if heat.heaters[0].state == "fault" || heat.heaters[1].state == "fault" || heat.heaters[2].state == "fault" || heat.heaters[3].state == "fault"
  M291 S1 R"Error" P"Heater fault detected"
  abort "Error: Heater fault detected"

M291 S5 J1 F250 L0 H450 R"Set Left Tool Temperature" P"Please set the temperature for the filament previously loaded in the Left Tool.<br>If new machine, set to 250°C"
var ll = input
  
M291 S5 J1 F{var.ll} L0 H450 R"Set Right Tool Temperature" P"Please set the temperature for the filament previously loaded in the Right Tool.<br>If new machine, set to 250°C"
var rr = input

var delta = -50

M568 P0 R{var.ll + var.delta} S{var.ll + var.delta}
M568 P1 R{var.rr + var.delta} S{var.rr + var.delta}
M568 P2 R{var.ll + var.delta,var.rr + var.delta} S{var.ll + var.delta,var.rr + var.delta}
M568 P3 R{var.ll + var.delta,var.rr + var.delta} S{var.ll + var.delta,var.rr + var.delta}

M568 P0 A2
M568 P1 A2


M291 S2 R"Please Remove the Build Plate" P"To avoid damaging your machine, remove the build plate from the build platform.<br>Click ""OK"" when you are ready to proceed."

if !move.axes[0].homed || !move.axes[1].homed || !move.axes[2].homed || !move.axes[3].homed
  M291 S0 T15 R"Homing Axes" P"Axes are not homed. Homing now. Please wait..."
  M98 P"0:/sys/homeall.g" S1

if state.currentTool != 0
  T0

G90
G1 X-999 U999 Y-75 F18000

M116 P0 S10
M116 P1 S10

T3
M83                 ; relative extruder moves
G1 E-50 F{60}*{10}   ; retract filament

M98 P"0:/sys/nozzlewipe.g" C1
M400
while iterations < 2
  M98 P"0:/sys/nozzlewipe.g" L1 C1
  M400

G1 F18000 X-50 Y-150 Z125  ; Move tools to the cleaning position

M568 P3 A0

M291 S4 K{"Nozzles are Clean","Cancel"} R"Please Clean Both Nozzles" P"Use a metal brush to clean both nozzles thoroughly to prevent machine damage."

if input == 1
  ; User cancelled
  M568 P0 S0 R0
  M568 P1 S0 R0
  M568 P2 S0 R0
  M568 P3 S0 R0
  abort "Calibration cancelled by user"

M291 S4 K{"Heat Breaks are All the Way Up","Cancel"} R"Verify Heat Break Position" P"Ensure both heat breaks are pushed all the way up into the heat sink. They must NOT stick out more than 1mm.<br><br>wiki.visionminer.com/home/22IDEX/V3/AutoCalibration"

if input == 1
  ; User cancelled
  M568 P0 S0 R0
  M568 P1 S0 R0
  M568 P2 S0 R0
  M568 P3 S0 R0
  abort "Calibration cancelled by user"

M568 P3 A2

M98 P"0:/sys/homeall.g" S1 L1

G29 S2     ; disable Mesh Bed Leveling
M290 R0 S0
M208 Z-5 S1
M558 K0 P8 C"1.io4.in" H5 F100 T18000              ; define Z probe parameters
M98 P"0:/sys/user/actions/ProbeOffset.g"           ; load global variables
T0
G1 U999 F18000
M42 P4 S1                                              ; Turn on relay






M98 P"0:/macros/System/Calibration/QC/AutoCal/Tool Height Auto Calibration" A1
M400

M98 P"0:/macros/System/Calibration/QC/AutoCal/Z - Offset Calibration" A1
M400

if global.xCompMode == "manual"
  echo "Skipping Mesh Bed calibration because compensation mode is manual"
else
  M98 P"0:/macros/System/Calibration/QC/AutoCal/Mesh Bed Calibration" A1
  M400

; Check if either XY squaring or steps/mm calibration is enabled
var runCalibration = false

; Load both mode states
M98 P"0:/sys/user/variables/XySquareMode.g"
M98 P"0:/sys/user/variables/StepsCalibration.g"
M98 P"0:/sys/user/actions/StepsCalibration.g"

; Check XY squaring mode (enabled if mode is "auto")
if global.xySquareMode == "auto"
  set var.runCalibration = true

; Check steps/mm calibration mode (enabled if true)
if global.stepsCalibration == true
  set var.runCalibration = true

; Run calibration only if at least one mode is enabled
if var.runCalibration
  M98 P"0:/macros/System/Calibration/QC/AutoCal/XY Auto Squaring" A1
  M400
  M98 P"0:/sys/xy_squaring.g"
  M400
else
  echo "Skipping XY Auto Squaring - both XY squaring and steps/mm calibration are disabled"

M98 P"0:/macros/System/Calibration/QC/AutoCal/XY - Offset Calibration" A1
M400



M568 P0 S0 R0
M568 P1 S0 R0
M568 P2 S0 R0
M568 P3 S0 R0

M208 Z0 S1
M558 K0 P8 C"1.io4.in" H5 F300 T18000
M98 P"0:/sys/user/actions/ProbeOffset.g"

M98 P"0:/sys/detachedcheck.g"

G90
G1 X-999 U999 Y150 Z100 F18000

; Build calibration results message
var msg = "Auto Calibration Successful"
set var.msg = var.msg ^ "<br>Tool 1 Z Offset = " ^ global.tool1ZOffset ^ " mm"
set var.msg = var.msg ^ "<br>Z-Offset = " ^ global.zOffset ^ " mm"
set var.msg = var.msg ^ "<br>Tool 1 Y-Offset = " ^ global.yOffset ^ " mm"
set var.msg = var.msg ^ "<br>Tool 1 U-Offset = " ^ global.uOffset ^ " mm"
set var.msg = var.msg ^ "<br>XY Skew = " ^ global.xySquareAuto ^ " mm"
M291 S2 R"Calibration Complete" P{var.msg}